﻿using SimpleServiceBus.Bus.Pipeline.PipelineComponents;
using SimpleServiceBus.Bus.Pipeline.PipelineComponents.MessageFiltering;
using SimpleServiceBus.Bus.Pipeline.PipelineComponents.MessageLogging;
using SimpleServiceBus.Endpoint;
using SimpleServiceBus.Utilities.ObjectBuilder;

namespace SimpleServiceBus.Bus.Pipeline
{
    public class DefaultMessagePipelineFactory : EndpointServiceBase,IMessagePipelineFactory
    {
        #region IMessagePipelineFactory Members

        public IMessagePipeline CreatePipelineFor(MessageEnvelope messageEnvelope, PipelineDirection direction)
        {
            if (direction == PipelineDirection.Send)
                return CreateSendPipelineFor(messageEnvelope);

            return CreateReceivePipelineFor(messageEnvelope);
        }

        #endregion

        public virtual IMessagePipeline CreateReceivePipelineFor(MessageEnvelope messageEnvelope)
        {
            var components = new IMessagePipelineComponent[]
                                 {
                                     new MessageBodySerializationComponent(),
                                     new MessageHeaderGeneratorComponent(),
                                     new MessageFilterComponent(),
                                     new MessageLoggingComponent(),
                                     new LocalCallbackDispatcherComponent(),
                                     new MessageHandlerDispatcherComponent()
                                 };

            var messagePipeline = CreatePipeline(messageEnvelope,PipelineDirection.Receive,components);
            
            return messagePipeline;
        }

        public virtual IMessagePipeline CreateSendPipelineFor(MessageEnvelope messageEnvelope)
        {
            var components = new IMessagePipelineComponent[]
                                 {
                                     new MessageHeaderGeneratorComponent(),
                                     new MessageFilterComponent(),
                                     new MessageLoggingComponent(),
                                     new MessageBodySerializationComponent()
                                 };

            IMessagePipeline messagePipeline = CreatePipeline(messageEnvelope,PipelineDirection.Send,components);
            return messagePipeline;
        }

        protected virtual IMessagePipeline CreatePipeline(MessageEnvelope messageEnvelope,PipelineDirection direction,params IMessagePipelineComponent[] components)
        {
            var factory = ServiceManager.GetService<IObjectBuilderService>();
            
            IMessagePipeline pipeline;

            if (factory != null)
                pipeline = factory.BuildService<IMessagePipeline, MessagePipeline>();
            else
                pipeline = new MessagePipeline();

            pipeline.Initialize(messageEnvelope, Endpoint, direction, components);

            return pipeline;
        }

        protected override void ShutDownService()
        {
        }

        protected override void StartService()
        {
        }
    }
}